home *** CD-ROM | disk | FTP | other *** search
/ Graphics & Sound Program…ng Techniques for the Mac / Graphics and Sound Programming Techniques for the Mac.iso / M&T Graphics & Sound Examples / Metrowerks Versions / C02 Sound Playing / P06 More Snd Commands / MoreSndCommands.c next >
Encoding:
C/C++ Source or Header  |  1995-08-05  |  9.2 KB  |  387 lines  |  [TEXT/MMCC]

  1. //____________________________________________________________
  2. //    MoreSndCommands.c
  3. //
  4. //    Copyright © Dan Parks Sydow, 1995
  5. //    From the book:
  6. //    "Graphics and Sound Programming Techniques for the Mac",
  7. //    M&T Books, 1995
  8.  
  9.  
  10. //____________________________________________________________
  11.  
  12. #include <Sound.h>
  13.  
  14.  
  15. //____________________________________________________________
  16.  
  17. pascal void    SoundChannelCallback( SndChannelPtr, SndCommand );
  18. OSErr          InstallCallbackCommand( SndChannelPtr );
  19. void           CleanUpSoundIfFinished( void );
  20. void           StopSoundPlaying( void );
  21. void           PlaySoundResourceAsynch( short );
  22. void           AnimateWhileSoundPlays( void );
  23. OSErr          SetSoundAmplitude( SndChannelPtr, short );
  24. OSErr          SetSoundRate( SndChannelPtr, long );    
  25. void           InitializeToolbox( void );
  26. void           OpenDisplayWindow( void );
  27. void           LoadAndSetupPicture( void );
  28. void           MovePictureOnePixel( void );
  29. SndChannelPtr  OpenOneAsynchSoundChannel( void );
  30. OSErr          DisposeOneSoundChannel( SndChannelPtr );
  31.  
  32.  
  33. //____________________________________________________________
  34.  
  35. #define      rMusicSound               9000
  36. #define      rDisplayWindow             128
  37. #define      rBearPicture               128
  38.  
  39. #define      k11kHzFreqRate      0x00008000
  40. #define      k22kHzFreqRate      0x00010000
  41. #define      k44kHzFreqRate      0x00020000
  42. #define      k66kHzFreqRate      0x00030000
  43.  
  44.  
  45. //____________________________________________________________
  46.  
  47. short          gSoundPlaying   = false;
  48. Boolean        gCallbackExecuted = false;
  49. SndChannelPtr  gSoundChannel     = nil;
  50. Handle         gSoundHandle      = nil;
  51. Boolean        gDone             = false;
  52. PicHandle      gThePicture;
  53. Rect           gTheRect;
  54.  
  55.  
  56. //____________________________________________________________
  57.  
  58. void  main( void )
  59. {
  60.    NumVersion   theSndMgrVers;      
  61.    EventRecord  theEvent;
  62.    
  63.    InitializeToolbox();
  64.    
  65.    theSndMgrVers = SndSoundManagerVersion();   
  66.    if ( theSndMgrVers.majorRev < 3 )
  67.       ExitToShell();
  68.    
  69.    OpenDisplayWindow();   
  70.    LoadAndSetupPicture(); 
  71.  
  72.    while ( gDone == false )
  73.    {
  74.       WaitNextEvent( everyEvent, &theEvent, 15L, nil );
  75.     
  76.       switch ( theEvent.what )
  77.       {
  78.          case mouseDown:
  79.             gDone = true;
  80.             break;
  81.           
  82.          case keyDown:
  83.             PlaySoundResourceAsynch( rMusicSound );
  84.             break;
  85.       }
  86.    } 
  87. }
  88.    
  89.  
  90. //____________________________________________________________
  91.  
  92. OSErr  SetSoundRate( SndChannelPtr theChannel, long theRate )
  93. {
  94.    SndCommand  theCommand;
  95.    OSErr       theError;
  96.    
  97.    theCommand.cmd = rateCmd;
  98.    theCommand.param1 = 0;
  99.    theCommand.param2 = theRate;
  100.    
  101.    theError = SndDoImmediate( theChannel, &theCommand );
  102.    
  103.    return ( theError );
  104. }
  105.  
  106.  
  107. //____________________________________________________________
  108.  
  109. OSErr  SetSoundAmplitude( SndChannelPtr theChannel, short theAmp )
  110. {
  111.    SndCommand  theCommand;
  112.    OSErr       theError;
  113.    
  114.    theCommand.cmd = ampCmd;
  115.    theCommand.param1 = theAmp;
  116.    theCommand.param2 = 0;
  117.    
  118.    theError = SndDoImmediate( theChannel, &theCommand );
  119.    
  120.    return ( theError );
  121. }
  122.  
  123.  
  124. //____________________________________________________________
  125.  
  126. void  PlaySoundResourceAsynch( short theResID )
  127. {
  128.    OSErr  theError;
  129.    
  130.    if ( gSoundChannel != nil )
  131.       StopSoundPlaying();
  132.       
  133.    gSoundChannel = OpenOneAsynchSoundChannel();
  134.    if ( gSoundChannel == nil )
  135.       ExitToShell();
  136.       
  137.    gSoundHandle = GetResource( 'snd ', theResID );
  138.    if ( gSoundHandle == nil )
  139.       ExitToShell();
  140.    
  141.    DetachResource( gSoundHandle );      
  142.    HLock( gSoundHandle );
  143.    
  144.    gSoundPlaying = true;
  145.    
  146.    theError = SndPlay( gSoundChannel, (SndListHandle)gSoundHandle, true );
  147.       
  148.    if ( theError == noErr )
  149.       theError = InstallCallbackCommand( gSoundChannel );
  150.    else
  151.       ExitToShell();
  152.       
  153.    AnimateWhileSoundPlays();
  154. }
  155.   
  156.  
  157. //____________________________________________________________
  158.  
  159. void  AnimateWhileSoundPlays( void )
  160. {
  161.    EventRecord  theEvt;
  162.    Boolean      loopDone = false;
  163.    char         theChar;
  164.    OSErr        theError;
  165.    short        theAmplitude = 255;
  166.    
  167.    while ( loopDone == false )
  168.    {
  169.       CleanUpSoundIfFinished();
  170.       
  171.       if ( gSoundPlaying == true )
  172.          MovePictureOnePixel();
  173.       else
  174.          loopDone = true;
  175.  
  176.       WaitNextEvent( everyEvent, &theEvt, 15L, nil );
  177.     
  178.       switch ( theEvt.what )
  179.       {       
  180.          case keyDown:
  181.             theChar = theEvt.message & charCodeMask;
  182.             switch ( theChar )
  183.             {      
  184.                case '+': 
  185.                   if ( theAmplitude <= 225 )
  186.                      theAmplitude += 30;
  187.                   theError = SetSoundAmplitude( gSoundChannel, theAmplitude );
  188.                   if ( theError != noErr )
  189.                      ExitToShell();
  190.                   break;
  191.                case '-': 
  192.                   if ( theAmplitude >= 30 )
  193.                      theAmplitude -= 30;
  194.                   theError = SetSoundAmplitude( gSoundChannel, theAmplitude );
  195.                   if ( theError != noErr )
  196.                      ExitToShell();
  197.                   break;
  198.                case 'p': 
  199.                   theError = SetSoundRate( gSoundChannel, k22kHzFreqRate );
  200.                   if ( theError != noErr )
  201.                      ExitToShell();
  202.                   break;
  203.                case 's': 
  204.                   theError = SetSoundRate( gSoundChannel, k11kHzFreqRate );
  205.                   if ( theError != noErr )
  206.                      ExitToShell();
  207.                   break;
  208.                case 'f': 
  209.                   theError = SetSoundRate( gSoundChannel, k66kHzFreqRate );
  210.                   if ( theError != noErr )
  211.                      ExitToShell();
  212.                   break;
  213.                default:
  214.                   StopSoundPlaying();
  215.                   loopDone = true;
  216.                   break;
  217.             }
  218.             break;
  219.       }
  220.    } 
  221. }
  222.  
  223.  
  224. //____________________________________________________________
  225.  
  226. void  StopSoundPlaying( void )
  227. {
  228.    if ( gSoundChannel != nil )
  229.    {
  230.       gCallbackExecuted = true;
  231.       gSoundPlaying = false;
  232.    }
  233.    CleanUpSoundIfFinished();
  234. }
  235.  
  236.  
  237. //____________________________________________________________
  238.  
  239. void  CleanUpSoundIfFinished( void )
  240. {
  241.    OSErr  theError;
  242.    
  243.    if ( gCallbackExecuted == true ) 
  244.    {
  245.       HUnlock( gSoundHandle );
  246.       ReleaseResource( gSoundHandle );
  247.       gSoundHandle = nil;
  248.       
  249.       theError = DisposeOneSoundChannel( gSoundChannel );
  250.       if ( theError != noErr )
  251.          ExitToShell();
  252.          
  253.       gSoundChannel = nil;
  254.       gCallbackExecuted = false;
  255.    }
  256. }
  257.  
  258.  
  259. //____________________________________________________________
  260.  
  261. OSErr  InstallCallbackCommand( SndChannelPtr theChannel )
  262. {
  263.    OSErr       theError;
  264.    SndCommand  theCommand;
  265.    
  266.    theCommand.cmd    = callBackCmd;
  267.    theCommand.param1 = 0;
  268.    #ifndef powerc
  269.       theCommand.param2 = SetCurrentA5();
  270.    #else
  271.       theCommand.param2 = 0;
  272.    #endif
  273.    
  274.    theError = SndDoCommand( theChannel, &theCommand, true );
  275.    
  276.    return ( theError );
  277. }
  278.  
  279.  
  280. //____________________________________________________________
  281.  
  282. pascal void  SoundChannelCallback( SndChannelPtr theChannel, SndCommand theCommand )
  283. {
  284.    long  theA5;
  285.    
  286.    #ifndef powerc
  287.       theA5 = SetA5( theCommand.param2 );
  288.    #endif
  289.       
  290.    gCallbackExecuted = true;
  291.    gSoundPlaying = false;
  292.       
  293.    #ifndef powerc
  294.       theA5 = SetA5( theA5 ); 
  295.    #endif
  296. }
  297.  
  298.  
  299.  
  300. //____________________________________________________________
  301.  
  302. SndChannelPtr  OpenOneAsynchSoundChannel( void )
  303. {
  304.    SndChannelPtr   theChannel;   
  305.    OSErr           theError;
  306.    SndCallBackUPP  theCallBackUPP;
  307.  
  308.    theCallBackUPP = NewSndCallBackProc( SoundChannelCallback );
  309.    
  310.    theChannel = nil;
  311.    theError = SndNewChannel( &theChannel, 0, 0, theCallBackUPP );
  312.    
  313.    if ( theError != noErr )
  314.    {
  315.       DisposePtr( (Ptr)theChannel );
  316.       theChannel = nil;
  317.    }
  318.       
  319.    return ( theChannel );
  320. }
  321.  
  322.  
  323. //____________________________________________________________
  324.  
  325. OSErr  DisposeOneSoundChannel( SndChannelPtr theChannel )
  326. {
  327.    OSErr  theError;
  328.    
  329.    theError = SndDisposeChannel( theChannel, true );
  330.    DisposePtr( (Ptr)theChannel );
  331.    
  332.    return ( theError );
  333. }
  334.  
  335.  
  336. //____________________________________________________________
  337.  
  338. void  InitializeToolbox( void )
  339. {
  340.    InitGraf( &qd.thePort );
  341.    InitFonts();
  342.    InitWindows();
  343.    InitMenus();
  344.    TEInit();
  345.    InitDialogs( 0L );
  346.    FlushEvents( everyEvent, 0 );
  347.    InitCursor();
  348. }
  349.  
  350.  
  351. //____________________________________________________________
  352.  
  353. void  OpenDisplayWindow( void )
  354. {
  355.    WindowPtr  theWindow;
  356.  
  357.    theWindow = GetNewWindow( rDisplayWindow, nil, (WindowPtr)-1L );
  358.    ShowWindow( theWindow );
  359.    SetPort( theWindow );
  360. }
  361.  
  362.  
  363. //____________________________________________________________
  364.  
  365. void  LoadAndSetupPicture( void )
  366. {
  367.    short  theWidth;
  368.    short  theHeight;
  369.    short  left = 475;
  370.    short  top = 10;
  371.  
  372.    gThePicture = GetPicture( rBearPicture );
  373.    gTheRect = (**gThePicture).picFrame;
  374.    theWidth = gTheRect.right - gTheRect.left;
  375.    theHeight = gTheRect.bottom - gTheRect.top;
  376.    SetRect( &gTheRect, left, top, left + theWidth, top + theHeight );
  377. }   
  378.     
  379.  
  380. //____________________________________________________________
  381.  
  382. void  MovePictureOnePixel( void )
  383. {
  384.    OffsetRect( &gTheRect, -1, 0 );
  385.    DrawPicture( gThePicture, &gTheRect );
  386. }
  387.